#pragma once
#include <vector>
#include <string>
#include <cassert>
#include <cstring>

class Buffer
{
public:
    Buffer(size_t initSize = 4096);
    
    ~Buffer();
    
    bool append(const std::string &data);
    
    bool append(const char *data, size_t len);
    
    std::string retrieve(size_t len);
    
    std::string retrieveAll();

    template<typename T>
    T retriveAs(){
        T res;
        if(readableSize() < sizeof(T)){
            return res;
        }
        memcpy(&res,buffer_.data()+readStart_,sizeof(T));
        readStart_ += sizeof(T);
        return res;
    }

    size_t availableSize();
    
    size_t readableSize();

    unsigned char* data();

private:
    bool enableWrite(size_t size);

private:
    size_t readStart_;
    size_t writeStart_;
    std::vector<unsigned char> buffer_;
};
